#ifndef COMMAND_PARSER_H
#define COMMAND_PARSER_H

namespace egear{namespace parser{

/*
 * CMD [Option ...] [arg]
 *
 * CMD's:
 * download    create a new transmittion
 * query       query the state of a transmittion
 * start       start a transmittion
 * stop        stop a transmittion
 * remove      remove a transmittion
 *
 * Format for download:
 *
 * download [-f filename] [-d directory] [-u]URL
 *
 * or:
 * download <protocol> <URL|sourcefile(like bt)> <destination>
 * The above uses fixes number of argv to easy parsing.
 *
 *
 *******************************************************************
 * Here is some example we are thinking of.
 *
 * ********** from client *************
 * *********** task control *********
 * download <-f file> <-d directory> <-u> url.
 * start taskid.
 * stop taskid.
 * pause taskid.
 * remove taskid.
 * increase taskid.
 * decrease taskid.
 * ************** status ************
 * query taskid.
 * keeplive.
 * ************** settings ************
 * set key value.
 * get key.
 *
 * ************ from server ************
 * ************ operator ***************
 * 100 succeed
 * 101 failed
 * 102 operator not supported
 * 103 unknown operator
 * TODO
 * ************ query result ***********
 * 200 <speed> <finished size> <resouce/seed>
 * ************ announce ***************
 * 300 stated: taskid.
 * 301 size changed: taskid size.
 * 302 removed: taskid.
 * 303 stopped: taskid.
 * 304 added: taskid.
 * 
 * TODO
 */

enum CLIENT_INSTRUCTION_TYPE{
    C_NEW,
    C_REMOVE,
    C_START,
    C_STOP,
    C_SLEEP,
    C_PAUSE,
    C_QUERY,
    C_KEEP_ALIVE,
};

enum SERVER_INSTRUCTION_TYPE{
    S_SUCCESS,
    S_STATE,
    S_NEW,
    S_REMOVED,
    S_STARTED,
    S_STOPPED,
    S_SLEEPING,
    S_PAUSED,
};

struct Instruction{
    bool direct; /**< false means from client, true means from server. */
    int type; /**< value will be in SERVER_INSTRUCTION_TYPE if from server,
                   or CLIENT_INSTRUCTION_TYPE if from client */
    std::string str_arg1;
    std::string str_arg2;
    std::string str_arg3;
    int int_arg1;
    int int_arg2;
    int int_arg3;
};

class ParserInterface{
    /*
     * this class get commands as string frome the client Session,
     * and parse it into the format which Mediator can understand,
     * and also parse the result of the Mediator, and parse it to
     * client readable.     
     * It may be design to be stateless or stateful.
     */
public:
    Instruction UserToMediator(const std::string &cmd)=0;
    std::string MediatorToUser(const Instruction &instr)=0;
};

class TelnetCompatible: public ParserInterface{
    /*
     * a parer for a telnet-like client.
     * It is stateless.
     */
public:
    TelnetCompatible();
    Instruction UserToMediator(const std::string &cmd);
    std::string MediatorToUser(const Instruction &instr);
};

}}
#endif /* COMMAND_PARSER_H */
